

#ifndef Velyn_Noise_h
#define Velyn_Noise_h

#include "IDisplacement.h"

namespace Velyn {
    
    namespace Displacements {

        /*
         * Adds Noise to the object
         */

        class Noise : public IDisplacement {
            
        private:
            
            /*
             * Determines how much change is applied to each subdivision. The greater 
             * the number of subdivisions makes the change value smaller thus applying
             * less noise.
             */
            
            float change;
            
            /*
             * The initial value for the noise applied to the object.
             */
            
            float scale;
            
            /*
             * Number of subdivisions on the mesh used to determine how much noise
             * on the object. The greater number of subdivisions causes less noise.
             */
            
            int numberSubdivisions;
            
        public:
            
            /* Noise() {}
            
            ~Noise() {} */
            
            /*
             * Noise constructor that takes the number of subdivisions.
             */
            
            /* Noise(int numberSubdivisions) {
                
                // set the number of subdivisions
                this->numberSubdivisions = numberSubdivisions;
                
                // is the initial value for the change value
                scale = 1.0;
                
                // change is a value that determines the noise displacement
                // try with different value such as 0.5
                change = 0.3;
            } */
            
            /*
             * Noise constructor that takes the number of subdivisions and
             * and how much change is applied for each subdivision.
             */
            
            Noise(int numberSubdivisions, float change) {
                
                // the number of subdivisions on the mesh
                this->numberSubdivisions = numberSubdivisions;
                
                // the amount of change for each subdivision
                this->change = change;
                
                // the initial value of the noise applied to the object
                scale = 1.0;
            }
            
            /*
             * Displaces the noise operator to the object
             */
            
            virtual int displace(TriangleMesh* mesh) {   
                
                // for each subdivision 
                for(int subdivisions = 0; subdivisions < numberSubdivisions; subdivisions++) {
                    
                    // determines a scale by the number of subdivisions to the amount of change
                    // given. this scale determines the noise on the object
                    scale *= change;
                }
                
                // get the vertices
                Vertex* vertices = mesh->getVertices();
                
                // get the normals
                Normal* normals = mesh->getNormals();
                
                // for each vertex in the mesh
                for(int vertex = 0; vertex < mesh->numberVertices(); vertex++) {	
                    
                    // the randomNumber is the scale multiplyed by drand which
                    // goes from 0 to 1 to determine if it comes out or into the mesh
                    float randomNumber = 1.0f + scale * drand48(); // + scale/2;
                    
                    // multiplay the vertex by a randomNumber
                    vertices[vertex] *= randomNumber;
                    
                    // reset normal
                    normals[vertex] = vertices[vertex];
                    normals[vertex].normalize();
                }
                
                // can i return a value that idenitifies what vertices have noise
                // appilied to it?
                return 1;
                
            }	
            
        };
        
    }
    
}

#endif
